package comms;

import javax.microedition.io.SocketConnection;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

/**
 * Class which handles incoming Socket connections to prevent the main Thread
 * becoming blocked.
 * <p>
 * Handler continuously receives data until the sender closes the connection.
 * 
 * @author Kevin
 */
public class SocketAgentConnectionHandler extends Thread {
	
	//The ConnectionManager which created this object.
	private ConnectionManager manager;
	
	//The SocketConnection object for this connection.
	private SocketConnection currentConnection;
	
	//The Input and Output Streams for this connection.
	private InputStream inStream;
	private OutputStream outStream;
	
	//Whether this object is listening for connections of not.
	private boolean listening;
	
	//Indication of whether and agent has been received or not.
	private boolean agentReceived;

	/**
	 * Constructor which opens the required streams and starts this Thread
	 * running.
	 * 
	 * @param manager The ConnectionManager which created this object.
	 * @param connection The SocketConnection object which this Handler will use.
	 */
	public SocketAgentConnectionHandler(ConnectionManager manager, SocketConnection connection) {
		this.manager = manager;
		this.currentConnection = connection;
		this.listening = true;
		this.agentReceived = false;
		
		try {
			this.inStream = connection.openInputStream();
			this.outStream = connection.openOutputStream();
		} catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
		
		this.start();
	}
	
	/**
	 * The run method for this Thread; constantly receives data until the Stream
	 * is closed by the sender.
	 * 
	 */
	public void run() {
		StringBuffer buff = new StringBuffer(0);
		int streamChar = 0;
		
		try {
			while (this.listening && !this.agentReceived) {			
				streamChar = this.inStream.read();
				while (streamChar != -1) {
					buff.append((char)streamChar);
					streamChar = this.inStream.read();
				}
							
				if (streamChar == -1) {
					this.agentReceived = true;
					break;
				}
			}
		} catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
		this.manager.agentReceived(buff.toString().getBytes(), buff.length());
	}
	
	/**
	 * Close this connection safely.
	 *
	 */
	public void close() {
		this.listening = false;
		
		try {
			if (this.inStream != null) this.inStream.close();
			if (this.outStream != null) this.outStream.close();
			this.currentConnection.close();
		} catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
	}
}
